<?php


/**
 * 生成树
 */
function genTree($items, $id = 'id', $pid = "pid")
{
    $map = [];
    $tree = [];

    //拼凑title
    foreach ($items as &$it) {
        $it['children'] = [];
        //数据的ID名生成新的引用索引树
        $it['name'] = '[ID:' . $it['id'] . '] ' . $it['name'];
        $it['expand'] = true;
        $map[$it[$id]] = &$it;
    }

    foreach ($items as &$it) {
        $parent = &$map[$it[$pid]];
        if ($parent) {
            $parent['children'][] = &$it;
        } else {
            $tree[] = &$it;
        }
    }
    return $tree;
}

/**
 * @desc 根据两点间的经纬度计算距离
 * @param float $lat 纬度值
 * @param float $lng 经度值
 */
function getDistance($lat1, $lng1, $lat2, $lng2)
{
    $earthRadius = 6367000; //approximate radius of earth in meters

    /*
      Convert these degrees to radians
      to work with the formula
    */

    $lat1 = ($lat1 * pi()) / 180;
    $lng1 = ($lng1 * pi()) / 180;

    $lat2 = ($lat2 * pi()) / 180;
    $lng2 = ($lng2 * pi()) / 180;

    /*
      Using the
      Haversine formula

      http://en.wikipedia.org/wiki/Haversine_formula

      calculate the distance
    */

    $calcLongitude = $lng2 - $lng1;
    $calcLatitude = $lat2 - $lat1;
    $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
    $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
    $calculatedDistance = $earthRadius * $stepTwo;

    return round($calculatedDistance);
}

// http 请求
function sendRequest($url)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置否输出到页面
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //设置连接等待时间
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验\
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    //要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    $data = curl_exec($ch);
    curl_close($ch);

    return $data;

}

// http 请求 微信小程序二维码专用
function curlPostWx($url, $data)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置否输出到页面
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //设置连接等待时间
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    ////设置post方式提交
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    $post_data = json_encode($data);
    // dump($post_data);exit;
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    $data = curl_exec($ch);
    curl_close($ch);

    return $data;

}

// http 请求
function curlPost($url, $data)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置否输出到页面
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //设置连接等待时间
    ////设置post方式提交
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    $post_data = json_encode($data);
    // dump($post_data);exit;
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    $data = curl_exec($ch);
    curl_close($ch);

    return $data;

}


/**
 *  发送短信 中国建网sms
 */

function sendSms($msg = "", $mobile = "")
{
    $url = "http://utf8.api.smschinese.cn/?Uid=八角星科技&Key=6d33bcb50d858bd48cd9&smsMob=" . $mobile . "&smsText=" . $msg;

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置否输出到页面
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //设置连接等待时间
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    $data = curl_exec($ch);
    curl_close($ch);

    return $data;

}

/**
 *  发送短信 腾讯云短信
 */

function sendMsg($msg = "", $mobile = "")
{
    $random = rand(1000, 9999);
    $sdkappid = 1400091904;
    $appkey = 'd2ee279e9de33b0241607a8607a66b59';
    $time = time();

    $sig = hash('sha256', 'appkey=' . $appkey . '&random=' . $random . '&time=' . $time . '&mobile=' . $mobile);

    $url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms?sdkappid=" . $sdkappid . "&random=" . $random;

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置否输出到页面
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); //设置连接等待时间
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");

    // 设置请求方式
    curl_setopt($ch, CURLOPT_POST, 1);

    //设置post数据
    $post_data = array(
        "ext" => "",
        "extend" => "",
        "msg" => "你的验证码是" . $random,
        "sig" => $sig,
        "tel" => ['mobile' => $mobile, "nationcode" => "86"],
        "time" => $time,
        "type" => 0
    );
    $post_data = json_encode($post_data);
    // dump($post_data);exit;
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    $data = curl_exec($ch);
    curl_close($ch);

    return $data;

}

/**
 * 获得IP地址
 * @return type
 */
function getIp()
{
    if (isset($_SERVER['HTTP_CLIENT_IP']) && strcasecmp($_SERVER['HTTP_CLIENT_IP'], "unknown"))
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    else if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], "unknown"))
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if (isset($_SERVER['REMOTE_ADDR']) && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
        $ip = $_SERVER['REMOTE_ADDR'];
    else if (isset($_SERVER['REMOTE_ADDR']) && isset($_SERVER['REMOTE_ADDR']) && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
        $ip = $_SERVER['REMOTE_ADDR'];
    else
        $ip = "";
    $ip = filter_var($ip, FILTER_VALIDATE_IP);
    return ($ip);
}

/**
 * 判断是否为MD5
 */
function isMd5($password)
{
    return preg_match("/^[a-f0-9]{32}$/", $password);
}

/**
 * 验证邮箱号码是否正确
 * @param type $mail 邮箱
 * @return boolean
 */
function checkEmail($mail = '')
{
    if (mb_strlen($mail) < 5) {
        return false;
    }
    $res = "/^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/";
    if (preg_match($res, $mail)) {
        return true;
    } else {
        return false;
    }
}

/**
 * 是否是手机号码
 * @param string $mobile 手机号码
 * @return boolean
 */
function checkMobile($mobile)
{
    if (!is_numeric($mobile)) {
        return false;
    }
    if (strlen($mobile) != 11 || !preg_match('#^1[\d][\d]{9}$#', $mobile)) {
        return false;
    } else {
        return true;
    }
}

/**
 * 是否是身份证
 * @param string $IDCard 身份证
 * @return boolean
 */
function checkIDCard($IDCard)
{
    /*if (!is_numeric($IDCard)) {
        return false;
    }*/

 //   if (strlen($IDCard) != 18 || !preg_match('/(^\d(15)$)|((^\d{18}$))|(^\d{17}(\d|X|x)$)/', $IDCard)) {
  if (strlen($IDCard) != 18 || !preg_match('/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/', $IDCard)) {
        return false;
    } else {
        return true;
    }
}

/**
 * 是否合法的用户名
 * @param string $name 用户名
 * @return boolean
 */
function checkUserName($name)
{
    if (!$name || strlen($name) < 3) {
        return false;
    }
    if (checkEmail($name)) {
        return false; //'用户名不能是邮箱地址';
    }
    if (checkMobile($name)) {
        return false; //'用户名不能是手机号码';
    }
    return true;
}

/**
 * 发送邮件
 * @param string $youjian 邮箱号码
 * @param string $title 标题
 * @param string $content 内容
 * @param string $fromname 署名
 * @return boolean
 */
function sendEmail($youjian, $title = '', $content = '', $fromname = "")
{
    if (!checkEmail($youjian)) {
        return false;
    }
    $config = C("mail");
    $fromname = $fromname == "" ? $config['fromName'] : $fromname;
    $mail = new \PHPMailer();
    $mail->IsSMTP();
    $mail->CharSet = $config['big'];
    $mail->AddAddress($youjian);
    $mail->Body = $content;
    $mail->From = $config['from'];
    $mail->FromName = $fromname;
    $mail->Subject = $title;
    $mail->Host = $config['stmp_host'];
    $mail->SMTPAuth = $config['MAIL_AUTH'];
    $mail->Username = $config['user'];
    $mail->Password = $config['pass'];
    $mail->IsHTML($config['MAIL_HTML']);
    $res = $mail->Send();
    return $res;
}

/**
 * 获取 IP  地理位置
 * 淘宝IP接口
 * @Return: array
 */
function getCity($ip = '')
{
    if ($ip == '') {
        $url = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json";
        $ip = json_decode(file_get_contents($url), true);
        $data = $ip;
    } else {
        $url = "http://ip.taobao.com/service/getIpInfo.php?ip=" . $ip;
        $ip = json_decode(file_get_contents($url));
        if ((string)$ip->code == '1') {
            return false;
        }
        $data = (array)$ip->data;
    }

    return $data;
}

/**
 * 创建文件目录
 * @param type $dir
 * @param type $mode
 * @return boolean
 */
function mkdirs($dir, $mode = 0777)
{
    if (is_dir($dir) || @mkdir($dir, $mode))
        return TRUE;
    if (!mkdirs(dirname($dir), $mode))
        return FALSE;
    return @mkdir($dir, $mode);
}

/**
 * 隐藏字符串
 * @param string $str 手机或邮箱
 * @return string
 */
function hideStr($str)
{
    if (checkEmail($str)) {
        $mail = explode('@', $str);
        $prevfix = (strlen($mail[0]) < 4) ? "" : substr($str, 0, 3); //邮箱前缀
        $count = 0;
        $str = preg_replace('/([\d\w+_-]{0,100})@/', '***@', $str, -1, $count);
        $rs = $prevfix . $str;
        return $rs;
    }
    return substr($str, 0, 3) . '****' . substr($str, 7, 4);
}

/**
 * 加密串
 * @param type $string 要加密的对象
 * @param type $operation 是加密还是解密
 * @param type $key 密钥
 * @param type $expiry
 * @return string
 */
function encrypt($string, $operation = 'ENCODE', $key = '', $expiry = 0)
{
    if ($operation == 'DECODE') {
        $string = str_replace('_', '/', $string);
    }
    $key_length = 4;
    $config = C('systems');
    $key = md5($key != '' ? $key : $config["code"]);
    $fixedkey = md5($key);
    $egiskeys = md5(substr($fixedkey, 16, 16));
    $runtokey = $key_length ? ($operation == 'ENCODE' ? substr(md5(microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';
    $keys = md5(substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));
    $string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));
    $i = 0;
    $result = '';
    $string_length = strlen($string);
    for ($i = 0; $i < $string_length; $i++) {
        $result .= chr(ord($string{$i}) ^ ord($keys{$i % 32}));
    }
    if ($operation == 'ENCODE') {
        $retstrs = str_replace('=', '', base64_encode($result));
        $retstrs = str_replace('/', '_', $retstrs);
        return $runtokey . $retstrs;
    } else {
        if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $egiskeys), 0, 16)) {
            return substr($result, 26);
        } else {
            return '';
        }
    }
}

/**
 * 删除指定文件
 * @param type $path
 * @param type $fileName
 */
function rmFile($path, $fileName)
{
    //去除空格
    $path = preg_replace('/(\/){2,}|{\\\}{1,}/', '/', $path);
    //得到完整目录
    $path .= $fileName;
    //判断此文件是否为一个文件目录
    if (is_dir($path)) {
        $file = scandir($path);
        foreach ($file as $key => $value) {
            unlink($path . '/' . $value);
        }
    }
}

/**
 * 获取用户的名称 用户的昵称>用户邮箱>用户手机号码>用户帐号
 * @param array or int $data
 * @return string 用户名称
 */
function getUserName($data)
{
    if (is_numeric($data)) {
        $data = M('user')->where('id', $data)->find();
    }
    $res = hideStr($data['mobile']);
    return $res;
}

/**
 * 生成当前时间 日期格式
 * @return type
 */
function createTime()
{
    return date('Y-m-d H:i:s', time());
}

/**
 * 生成当前日期
 * @return type
 */
function createToday()
{
    return date('Y-m-d', time());
}

/**
 * 转换数组 指定key 作为下标
 */
function key2key($data, $keys)
{
    $res = array();
    foreach ($data as $key => $value) {
        $res[$value[$keys]] = $value;
    }
    return $res;
}

/**
 * 把返回的数据集转换成Tree
 * @access public
 * @param array $list 要转换的数据集
 * @param string $pid parent标记字段
 * @param string $level level标记字段
 * @return array
 */
function list2Tree($list, $pk = 'id', $pid = 'pid', $child = 'child', $root = 0, $is_count = false)
{
    $tree = [];
    if (is_array($list)) {
        $refer = [];
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] = &$list[$key];
        }
        foreach ($list as $key => $data) {
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] = &$list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent = &$refer[$parentId];
                    $parent[$child][] = &$list[$key];
                    if ($is_count == true)
                        $parent['count'] = count($parent[$child]);
                }
            }
        }
    }
    return $tree;
}

/**
 * 生成订单号
 * @param string $str 前缀
 * @return string 订单号
 */
function createOrderCode($str = '')
{
    return $str . time() . substr(microtime(), 2, 6) . rand(0, 9);
}

function qrcode($url)
{
    if(!$url){
        $this->err('没有传url');
    }
    $savePath = APP_PATH . '/../Public/qrcode/';
    $webPath = '/qrcode/';
    $qrData = $url;
    $qrLevel = 'H';
    $qrSize = '8';
    $savePrefix = 'baJiaoStar';
    if($filename = createQRcode($savePath, $qrData, $qrLevel, $qrSize, $savePrefix)){
        $pic = $webPath . $filename;
    }
    return $pic;
}

/**
 * 功能：生成二维码
 * @param string $qrData 手机扫描后要跳转的网址
 * @param string $qrLevel 默认纠错比例 分为L、M、Q、H四个等级，H代表最高纠错能力
 * @param string $qrSize 二维码图大小，1－10可选，数字越大图片尺寸越大
 * @param string $savePath 图片存储路径
 * @param string $savePrefix 图片名称前缀
 */
function createQRcode($savePath, $qrData = 'PHP QR Code :)', $qrLevel = 'L', $qrSize = 4, $savePrefix = 'qrcode')
{
    require EXTEND_PATH . 'phpqrcode.php';
    if (!isset($savePath)) return '';
    //设置生成png图片的路径
    $PNG_TEMP_DIR = $savePath;

    //检测并创建生成文件夹
    if (!file_exists($PNG_TEMP_DIR)) {
        mkdir($PNG_TEMP_DIR);
    }
    $filename = $PNG_TEMP_DIR . 'test.png';
    $errorCorrectionLevel = 'L';
    if (isset($qrLevel) && in_array($qrLevel, ['L', 'M', 'Q', 'H'])) {
        $errorCorrectionLevel = $qrLevel;
    }
    $matrixPointSize = 4;
    if (isset($qrSize)) {
        $matrixPointSize = min(max((int)$qrSize, 1), 10);
    }
    if (isset($qrData)) {
        if (trim($qrData) == '') {
            die('data cannot be empty!');
        }
        //生成文件名 文件路径+图片名字前缀+md5(名称)+.png
        $filename = $PNG_TEMP_DIR . $savePrefix . md5($qrData . '|' . $errorCorrectionLevel . '|' . $matrixPointSize) . '.png';
        //开始生成
        \QRcode::png($qrData, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
    } else {
        //默认生成
        \QRcode::png('PHP QR Code :)', $filename, $errorCorrectionLevel, $matrixPointSize, 2);
    }
    if (file_exists($PNG_TEMP_DIR . basename($filename)))
        return basename($filename);
    else
        return FALSE;
}


/**
 * 根据经纬度和半径计算出范围
 * @param string $lat 纬度
 * @param String $lng 经度
 * @param float $radius 半径
 * @return Array 范围数组
 */
 function calcScope($lat, $lng, $radius) {
    $degree = (24901*1609)/360.0;
    $dpmLat = 1/$degree;

    $radiusLat = $dpmLat*$radius;
    $minLat = $lat - $radiusLat;    // 最小纬度
    $maxLat = $lat + $radiusLat;    // 最大纬度

    $mpdLng = $degree*cos($lat * (pi()/180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng*$radius;
    $minLng = $lng - $radiusLng;   // 最小经度
    $maxLng = $lng + $radiusLng;   // 最大经度

    /** 返回范围数组 */
     $getDistance = [
        'minLat'  => $minLat,
        'maxLat'  => $maxLat,
        'minLng'  => $minLng,
        'maxLng'  => $maxLng
    ];
    return  $getDistance;
}

/**
 * 两浮点型相减，保留来两位小数
 */
function subFloat($bigger = 0, $small = 0){
    return bcsub($bigger, $small, 2);
}

/**
 * 根据距离排序
 * @param $a
 * @param $b
 * @return int
 */
function distanceSort($a,$b){
    if($a->distance>$b->distance){
        return 1;
    }
    elseif($a->distance==$b->distance){
        return ($a->id>$b->id) ? 1:-1;

    }}






